﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.IO;
//using System.Runtime.InteropServices;
//using Microsoft.Win32.SafeHandles;
//using Coronox.SkyShell.Ntfs;

//namespace Coronox.SkyShell
//{


//    /// <summary>
//    /// Provides access to NTFS junction points in .Net.
//    /// </summary>
//    public static class JunctionPoint
//    {
//        /// <summary>
//        /// The file or directory is not a reparse point.
//        /// </summary>
//        private const int ERROR_NOT_A_REPARSE_POINT = 4390;

//        /// <summary>
//        /// The reparse point attribute cannot be set because it conflicts with an existing attribute.
//        /// </summary>
//        private const int ERROR_REPARSE_ATTRIBUTE_CONFLICT = 4391;

//        /// <summary>
//        /// The data present in the reparse point buffer is invalid.
//        /// </summary>
//        private const int ERROR_INVALID_REPARSE_DATA = 4392;

//        /// <summary>
//        /// The tag present in the reparse point buffer is invalid.
//        /// </summary>
//        private const int ERROR_REPARSE_TAG_INVALID = 4393;

//        /// <summary>
//        /// There is a mismatch between the tag specified in the request and the tag present in the reparse point.
//        /// </summary>
//        private const int ERROR_REPARSE_TAG_MISMATCH = 4394;

//        /// <summary>
//        /// Command to set the reparse point data block.
//        /// </summary>
//        private const int FSCTL_SET_REPARSE_POINT = 0x000900A4;

//        /// <summary>
//        /// Command to get the reparse point data block.
//        /// </summary>
//        private const int FSCTL_GET_REPARSE_POINT = 0x000900A8;

//        /// <summary>
//        /// Command to delete the reparse point data base.
//        /// </summary>
//        private const int FSCTL_DELETE_REPARSE_POINT = 0x000900AC;

//        /// <summary>
//        /// Reparse point tag used to identify mount points and junction points.
//        /// </summary>
//        private const uint IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003;

//        /// <summary>
//        /// This prefix indicates to NTFS that the path is to be treated as a non-interpreted
//        /// path in the virtual file system.
//        /// </summary>
//        private const string NonInterpretedPathPrefix = @"\??\";




      

//        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
//        private static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode,
//            IntPtr InBuffer, int nInBufferSize,
//            IntPtr OutBuffer, int nOutBufferSize,
//            out int pBytesReturned, IntPtr lpOverlapped);

//        [DllImport("kernel32.dll", SetLastError = true)]
//        private static extern IntPtr CreateFile(
//            string lpFileName,
//            SsxFileAccess dwDesiredAccess,
//            SsxFileShare dwShareMode,
//            IntPtr lpSecurityAttributes,
//            SsxFileMode dwCreationDisposition,
//            SsxFileAttributes dwFlagsAndAttributes,
//            IntPtr hTemplateFile);

//        /// <summary>
//        /// Creates a junction point from the specified directory to the specified target directory.
//        /// </summary>
//        /// <remarks>
//        /// Only works on NTFS.
//        /// </remarks>
//        /// <param name="junctionPoint">The junction point path</param>
//        /// <param name="targetDir">The target directory</param>
//        /// <param name="overwrite">If true overwrites an existing reparse point or empty directory</param>
//        /// <exception cref="IOException">Thrown when the junction point could not be created or when
//        /// an existing directory was found and <paramref name="overwrite" /> if false</exception>
//        //public static void Create(string junctionPoint, string targetDir, bool overwrite)
//        //{
//        //    targetDir = Path.GetFullPath(targetDir);

//        //    if (!Directory.Exists(targetDir))
//        //        throw new IOException("Target path does not exist or is not a directory.");

//        //    if (Directory.Exists(junctionPoint))
//        //    {
//        //        if (!overwrite)
//        //            throw new IOException("Directory already exists and overwrite parameter is false.");
//        //    }
//        //    else
//        //    {
//        //        Directory.CreateDirectory(junctionPoint);
//        //    }

//        //    using (SafeFileHandle handle = OpenReparsePoint(junctionPoint, SsxFileAccess.GenericWrite))
//        //    {
//        //        byte[] targetDirBytes = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + Path.GetFullPath(targetDir));

//        //        ReparseDataBuffer reparseDataBuffer = new ReparseDataBuffer();

//        //        reparseDataBuffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
//        //        reparseDataBuffer.ReparseDataLength = (ushort)(targetDirBytes.Length + 12);
//        //        reparseDataBuffer.SubstituteNameOffset = 0;
//        //        reparseDataBuffer.SubstituteNameLength = (ushort)targetDirBytes.Length;
//        //        reparseDataBuffer.PrintNameOffset = (ushort)(targetDirBytes.Length + 2);
//        //        reparseDataBuffer.PrintNameLength = 0;
//        //        reparseDataBuffer.PathBuffer = new byte[0x3ff0];
//        //        Array.Copy(targetDirBytes, reparseDataBuffer.PathBuffer, targetDirBytes.Length);

//        //        int inBufferSize = Marshal.SizeOf(reparseDataBuffer);
//        //        IntPtr inBuffer = Marshal.AllocHGlobal(inBufferSize);

//        //        try
//        //        {
//        //            Marshal.StructureToPtr(reparseDataBuffer, inBuffer, false);

//        //            int bytesReturned;
//        //            bool result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_SET_REPARSE_POINT,
//        //                inBuffer, targetDirBytes.Length + 20, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);

//        //            if (!result)
//        //                ThrowLastWin32Error("Unable to create junction point.");
//        //        }
//        //        finally
//        //        {
//        //            Marshal.FreeHGlobal(inBuffer);
//        //        }
//        //    }
//        //}

//        /// <summary>
//        /// Deletes a junction point at the specified source directory along with the directory itself.
//        /// Does nothing if the junction point does not exist.
//        /// </summary>
//        /// <remarks>
//        /// Only works on NTFS.
//        /// </remarks>
//        /// <param name="junctionPoint">The junction point path</param>
//        //public static void Delete(string junctionPoint)
//        //{
//        //    if (!Directory.Exists(junctionPoint))
//        //    {
//        //        if (File.Exists(junctionPoint))
//        //            throw new IOException("Path is not a junction point.");

//        //        return;
//        //    }

//        //    using (SafeFileHandle handle = OpenReparsePoint(junctionPoint, SsxFileAccess.GenericWrite))
//        //    {
//        //        ReparseDataBuffer reparseDataBuffer = new ReparseDataBuffer();

//        //        reparseDataBuffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
//        //        reparseDataBuffer.ReparseDataLength = 0;
//        //        reparseDataBuffer.PathBuffer = new byte[0x3ff0];

//        //        int inBufferSize = Marshal.SizeOf(reparseDataBuffer);
//        //        IntPtr inBuffer = Marshal.AllocHGlobal(inBufferSize);
//        //        try
//        //        {
//        //            Marshal.StructureToPtr(reparseDataBuffer, inBuffer, false);

//        //            int bytesReturned;
//        //            bool result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_DELETE_REPARSE_POINT,
//        //                inBuffer, 8, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);

//        //            if (!result)
//        //                ThrowLastWin32Error("Unable to delete junction point.");
//        //        }
//        //        finally
//        //        {
//        //            Marshal.FreeHGlobal(inBuffer);
//        //        }

//        //        try
//        //        {
//        //            Directory.Delete(junctionPoint);
//        //        }
//        //        catch (IOException ex)
//        //        {
//        //            throw new IOException("Unable to delete junction point.", ex);
//        //        }
//        //    }
//        //}

//        /// <summary>
//        /// Determines whether the specified path exists and refers to a junction point.
//        /// </summary>
//        /// <param name="path">The junction point path</param>
//        /// <returns>True if the specified path represents a junction point</returns>
//        /// <exception cref="IOException">Thrown if the specified path is invalid
//        /// or some other error occurs</exception>
//        //public static bool Exists(string path)
//        //{
//        //    if (!Directory.Exists(path))
//        //        return false;

//        //    using (SafeFileHandle handle = OpenReparsePoint(path, SsxFileAccess.GenericRead))
//        //    {
//        //        string target = InternalGetTarget(handle);
//        //        return target != null;
//        //    }
//        //}




  



      
//    }
//}


